<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="./vue.js"></script>
    <link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>

</head>
<!-- 
    自定义过渡的类名
    我们可以通过以下特性来自定义过渡类名：

    enter-class
    enter-active-class
    enter-to-class (2.1.8+)
    leave-class
    leave-active-class
    leave-to-class (2.1.8+)

    自定义过渡的类名优先级高于普通的类名，这样就能很好的与第三方（如：animate.css）的动画库结合使用。
 -->

<body>
    <div id="databinding">
        <button v-on:click="show = !show">Click Me</button>
        <transition name="custom-classes-transition" enter-active-class="animated tada" leave-active-class="animated bounceOutRight">
            <p v-if="show">小菜鸟学编程，学的不仅是技术，更是梦想</p>
        </transition>
    </div>
    <script>
        new Vue({
            el: "#databinding",
            data: {
                show: true
            }
        })
    </script>
</body>

<!-- 
    同时使用过渡和动画

    Vue 为了知道过渡的完成，必须设置相应的事件监听器。
    它可以是 transitionend 或 animationend ，这取决于给元素应用的 CSS 规则。
    如果你使用其中任何一种，Vue 能自动识别类型并设置监听。

    但是，在一些场景中，你需要给同一个元素同时设置两种过渡动效，
    比如 animation 很快的被触发并完成了，而 transition 效果还没结束。
    在这种情况中，你就需要使用 type 特性并设置 animation 或 transition 来明确声明你需要 Vue 监听的类型。

    显性的过渡持续时间

    在很多情况下，Vue 可以自动得出过渡效果的完成时机。
    默认情况下，Vue 会等待其在过渡效果的根元素的第一个 transitionend 或 animationend 事件。
    然而也可以不这样设定——比如，我们可以拥有一个精心编排的一系列过渡效果，
    其中一些嵌套的内部元素相比于过渡效果的根元素有延迟的或更长的过渡效果。

    在这种情况下你可以用 <transition> 组件上的 duration 属性定制一个显性的过渡持续时间 (以毫秒计)：
    
    <transition :duration="1000">...</transition>

    你也可以定制进入和移出的持续时间：

    <transition :duration="{ enter: 500, leave: 800 }">...</transition>
 -->

<!-- 
    JavaScript 钩子

    可以在属性中声明 JavaScript 钩子:
    
    HTML 代码：
    <transition
    v-on:before-enter="beforeEnter"
    v-on:enter="enter"
    v-on:after-enter="afterEnter"
    v-on:enter-cancelled="enterCancelled"
    
    v-on:before-leave="beforeLeave"
    v-on:leave="leave"
    v-on:after-leave="afterLeave"
    v-on:leave-cancelled="leaveCancelled"
    >
    //----HTML代码块-----//
    </transition>
    
    JavaScript 代码：
    // ...
    methods: {
    // --------
    // 进入中
    // --------
    
    beforeEnter: function (el) {
        // ...
    },
    // 此回调函数是可选项的设置
    // 与 CSS 结合时使用
    enter: function (el, done) {
        // ...
        done()
    },
    afterEnter: function (el) {
        // ...
    },
    enterCancelled: function (el) {
        // ...
    },
    
    // --------
    // 离开时
    // --------
    
    beforeLeave: function (el) {
        // ...
    },
    // 此回调函数是可选项的设置
    // 与 CSS 结合时使用
    leave: function (el, done) {
        // ...
        done()
    },
    afterLeave: function (el) {
        // ...
    },
    // leaveCancelled 只用于 v-show 中
    leaveCancelled: function (el) {
        // ...
    }
    }

    这些钩子函数可以结合 CSS transitions/animations 使用，也可以单独使用。

    当只用 JavaScript 过渡的时候，在 enter 和 leave 中必须使用 done 进行回调。
    否则，它们将被同步调用，过渡会立即完成。

    推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false"，Vue 会跳过 CSS 的检测。
    这也可以避免过渡过程中 CSS 的影响。
 -->

<body>
    <div id="databinding2">
        <button v-on:click="show = !show">Click Me</button>
        <transition v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:leave="leave" v-bind:css="false">
            <p v-if="show">小菜鸟学编程，学的不仅是技术，更是梦想</p>
        </transition>
    </div>

    <script>
        //如果show 一开始就是true ,那么会影响动画结果，会反方向执行动画
        new Vue({
            el: "#databinding2",
            data: {
                show: false
            },
            methods: {
                beforeEnter: el => {
                    el.style.opacity = 0
                    el.style.transformOrigin = "left"
                },
                enter: (el, done) => {
                    Velocity(el, {
                        opacity: 1,
                        fontSize: '1.4em'
                    }, {
                        duration: 300
                    })
                    Velocity(el, {
                        fontSize: '1em'
                    }, {
                        complate: done
                    })
                },
                leave: (el, done) => {
                    Velocity(el, {
                        translateX: '15px',
                        rotateZ: '50deg'
                    }, {
                        duration: 600
                    })
                    Velocity(el, {
                        rotateZ: '100deg'
                    }, {
                        loop: 2
                    })
                    Velocity(el, {
                        rotateZ: '45deg',
                        translateY: '30px',
                        translateX: "30px",
                        opacity: 0
                    }, {
                        complate: done
                    })
                }
            },
        })
    </script>
</body>

<!-- 初始渲染的过渡 可以通过 appear 特性设置节点在初始渲染的过渡 -->

<transition appear>
    <!-- ... -->
</transition>

<!-- 这里默认和进入/离开过渡一样，同样也可以自定义 CSS 类名。 -->

<transition appear appear-class="custom-appear-class" appear-to-class="custom-appear-to-class" (2.1.8+) appear-active-class="custom-appear-active-class">
    <!-- ... -->
</transition>

<!-- 自定义 JavaScript 钩子： -->

<transition appear v-on:before-appear="customBeforeAppearHook" v-on:appear="customAppearHook" v-on:after-appear="customAfterAppearHook" v-on:appear-cancelled="customAppearCancelledHook">
    <!-- ... -->
</transition>

<!-- 
    多个元素的过渡

    我们可以设置多个元素的过渡，一般列表与描述：

    需要注意的是当有相同标签名的元素切换时，
    需要通过 key 特性设置唯一的值来标记以让 Vue 区分它们，
    否则 Vue 为了效率只会替换相同标签内部的内容。 
-->

<transition>
    <table v-if="items.length > 0">
        <!-- ... -->
    </table>
    <p v-else>抱歉，没有找到您查找的内容。</p>
</transition>

<!-- 如下实例： -->

<transition>
    <button v-if="isEditing" key="save">
    Save
  </button>
    <button v-else key="edit">
    Edit
  </button>
</transition>

<!-- 
    在一些场景中，也可以通过给同一个元素的 key 特性设置不同的状态来代替 v-if 和 v-else，
    上面的例子可以重写为： -->

<transition>
    <button v-bind:key="isEditing">
    {{ isEditing ? 'Save' : 'Edit' }}
  </button>
</transition>

<!-- 使用多个 v-if 的多个元素的过渡可以重写为绑定了动态属性的单个元素过渡。例如： -->

<transition>
    <button v-if="docState === 'saved'" key="saved">
    Edit
  </button>
    <button v-if="docState === 'edited'" key="edited">
    Save
  </button>
    <button v-if="docState === 'editing'" key="editing">
    Cancel
  </button>
</transition>

<!-- 可以重写为： -->

<transition>
    <button v-bind:key="docState">
    {{ buttonMessage }}
  </button>
</transition>

<!-- 
    // ...
    computed: {
    buttonMessage: function () {
        switch (this.docState) {
        case 'saved': return 'Edit'
        case 'edited': return 'Save'
        case 'editing': return 'Cancel'
        }
    }
    } 
-->

</html>